import { ALL_HANDLES } from './Vue3DragResizeRotate'
import { initParent } from './hooks'
import { ContainerProvider, ReferenceLineMap, ResizingHandle, ResizingHandleStore } from './types'

export const IDENTITY = Symbol('Vue3DragResizeRotate')

export function filterHandles(handles: ResizingHandle[]): ResizingHandleStore[] {
  if (handles && handles.length > 0) {
    const result: ResizingHandleStore[] = []
    handles.forEach((item: ResizingHandle) => {
      ALL_HANDLES.forEach((allItem: ResizingHandleStore) => {
        if (allItem.direction === item) {
          result.push(allItem)
        }
      })
    })
    return result
  } else {
    return []
  }
}

export function getId(): string {
  return String(Math.random()).substring(2) + String(Date.now())
}
export const directionMap: { [propName: string]: number } = {
  tl: 135,
  tm: 0,
  tr: 45,
  ml: 90,
  mr: 90,
  bl: 45,
  bm: 0,
  br: 135,
}

export function getElSize(el: Element): {
  width: number
  height: number
  top: number
  left: number
} {
  // const style = window.getComputedStyle(el)
  // return {
  //   width: parseFloat(style.getPropertyValue('width')),
  //   height: parseFloat(style.getPropertyValue('height'))
  // }
  const rect = el.getBoundingClientRect()
  return {
    width: rect.width,
    height: rect.height,
    top: rect.top,
    left: rect.left,
  }
}

function createEventListenerFunction(type: 'addEventListener' | 'removeEventListener') {
  return <K extends keyof HTMLElementEventMap>(el: HTMLElement, events: K | K[], handler: any) => {
    if (!el) {
      return
    }
    if (typeof events === 'string') {
      events = [events]
    }
    events.forEach(e => el[type](e, handler, { passive: false }))
  }
}

export const addEvent = createEventListenerFunction('addEventListener')

export const removeEvent = createEventListenerFunction('removeEventListener')

export function getReferenceLineMap(
  containerProvider: ContainerProvider,
  parentSize: ReturnType<typeof initParent>,
  id?: string
): null | ReferenceLineMap {
  if (containerProvider.disabled.value) {
    return null
  }
  const referenceLine = {
    row: [] as number[],
    col: [] as number[],
  }
  const { parentWidth, parentHeight } = parentSize
  referenceLine.row.push(...containerProvider.adsorbRows)
  referenceLine.col.push(...containerProvider.adsorbCols)
  if (containerProvider.adsorbParent.value) {
    referenceLine.row.push(0, parentHeight.value, parentHeight.value / 2)
    referenceLine.col.push(0, parentWidth.value, parentWidth.value / 2)
  }
  const widgetPositionStore = containerProvider.getPositionStore(id)
  Object.values(widgetPositionStore).forEach(({ x, y, w, h }) => {
    referenceLine.row.push(y, y + h, y + h / 2)
    referenceLine.col.push(x, x + w, x + w / 2)
  })
  const referenceLineMap: ReferenceLineMap = {
    row: referenceLine.row.reduce((pre, cur) => {
      return { ...pre, [cur]: { min: cur - 5, max: cur + 5, value: cur } }
    }, {}),
    col: referenceLine.col.reduce((pre, cur) => {
      return { ...pre, [cur]: { min: cur - 5, max: cur + 5, value: cur } }
    }, {}),
  }
  return referenceLineMap
}

type Vector = {
  x: number
  y: number
}
export function getAngle(startVector: Vector, rotateVector: Vector): number {
  const { x: x1, y: y1 } = startVector
  const { x: x2, y: y2 } = rotateVector
  // const dot = x1 * x2 + y1 * y2
  // const det = x1 * y2 - y1 * x2
  // console.log(det, dot)
  // const angle = Math.atan2(det, dot) / Math.PI * 180
  // return (angle + 360) % 360

  const angle1 = Math.atan2(y1, x1) / (Math.PI / 180)
  const angle2 = Math.atan2(y2, x2) / (Math.PI / 180)
  return angle2 - angle1
}

export const getLength = (x: number, y: number): number => Math.sqrt(x * x + y * y)

// deg -> 弧度
export const degToRadian = (deg: number): number => (deg * Math.PI) / 180

export const cos = (deg: number): number => Math.cos(degToRadian(deg))
export const sin = (deg: number): number => Math.sin(degToRadian(deg))
